﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;

namespace SuperKit
{
    /// <summary>
    /// FindAndReplace.xaml 的交互逻辑
    /// </summary>
    public partial class FindAndReplace : Window {


        public delegate void FindAndReplaceAction(FindAndReplace form);

        public FindAndReplaceAction OnFind;
        public FindAndReplaceAction OnReplace;
        public FindAndReplaceAction OnReplaceAll;

        public bool UseRegex { get => checkUseRegex.IsChecked == true; set => checkUseRegex.IsChecked = value; }
        public bool IgnoreCase { get => checkCase.IsChecked == false; set => checkCase.IsChecked = (value == false); }
        public string FindText { get => txtFind.Text; set => txtFind.Text = value; }
        public string ReplaceText { get => txtReplace.Text; set => txtReplace.Text = value; }
        private static string LastFindText { get; set; }
        private static string LastReplaceText { get; set; }
        private static bool LastUseRegex { get; set; }
        private static bool LastIgnoreCase { get; set; }
        public bool FindEnable { 
            get => buttonFind.Visibility == Visibility.Visible; 
            set => buttonFind.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
        }
        public bool ReplaceEnable { 
            get => buttonReplace.Visibility == Visibility.Visible; 
            set => buttonReplace.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
        }
        public bool AllReplaceEnable { 
            get => buttonReplaceAll.Visibility == Visibility.Visible; 
            set => buttonReplaceAll.Visibility = value ? Visibility.Visible : Visibility.Collapsed;
        }


        public FindAndReplace() {
            InitializeComponent();
        }

        private void FindAndReplace_Load(object sender, RoutedEventArgs e) {
            FindText = LastFindText;
            ReplaceText = LastReplaceText;
            string.Compare(FindText, ReplaceText, StringComparison.OrdinalIgnoreCase);
        }

        private void buttonFind_Click(object sender, RoutedEventArgs e) {
            OnFind?.Invoke(this);
            RefreshLast();
        }

        private void buttonReplace_Click(object sender, RoutedEventArgs e) {
            OnReplace?.Invoke(this);
            RefreshLast();
        }

        private void buttonReplaceAll_Click(object sender, RoutedEventArgs e) {
            OnReplaceAll?.Invoke(this);
            RefreshLast();
        }

        private void buttonCancel_Click(object sender, RoutedEventArgs e) {
            Close();
        }

        private void RefreshLast() {
            LastFindText = FindText;
            LastReplaceText = ReplaceText;
            LastUseRegex = UseRegex;
            LastIgnoreCase = IgnoreCase;
        }

        public string Replace(string s) {
            if (Kit.IsEmpty(FindText)) {
                return s;
            }

            if (UseRegex) {
                Regex regex = new Regex(FindText);
                s = regex.Replace(s, ReplaceText);
            } else {
                if (IgnoreCase) {
                    int pointer = 0;
                    while (true) {
                        int index = s.IndexOf(FindText, pointer, StringComparison.OrdinalIgnoreCase);
                        if (index == -1) {
                            break;
                        }
                        string front = s.Substring(0, index);
                        string rear = s.Substring(index + FindText.Length);
                        s = front + ReplaceText + rear;
                        pointer = index + ReplaceText.Length;
                    }
                } else {
                    s = s.Replace(FindText, ReplaceText);
                }
            }
            return s;
        }
    }
}
